/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 idle_processor.h

	$Header: /heroes4/idle_processor.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( IDLE_PROCESSOR_H_INCLUDED )
#define IDLE_PROCESSOR_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <list>
#include "counted_ptr.h"
#include "sized_int_types.h"
/////////////////////////////////////////////////////////////////////////////
// t_idle_processor

class t_idle_processor;

class t_idle_list : public std::list< t_idle_processor * >, public t_counted_object
{
};

typedef t_counted_ptr<t_idle_list> t_idle_list_ptr;
typedef t_idle_list::iterator      t_idle_iterator;

class t_idle_processor
{
public:
	// Static member functions
	static t_uint32 run();

	// Constructors/Destructor
	t_idle_processor( t_uint32 suspension_count = 0, t_uint32 delay = 20 );
	t_idle_processor( t_idle_processor const & other );
	virtual ~t_idle_processor();

	t_uint32	get_delay() const;
	t_uint32	get_next_time() const;
	bool		is_active() const;
	void		resume_idle_processing();
	void		set_delay( t_uint32 delay );
	void		set_next_time();
	void		set_next_time( t_uint32 arg );
	void		suspend_idle_processing();

protected:
	void insert();
	void remove();

	// Data members
	t_uint32		m_delay;
	t_idle_list_ptr m_list;
	t_idle_list_ptr m_running_list;
	t_idle_iterator m_list_position;
	t_uint32		m_next_update_time;
	t_uint32		m_suspension_count;

	// Member functions
	virtual void on_idle() = 0;
};

inline t_uint32 t_idle_processor::get_delay() const
{
	return m_delay;
}

inline t_uint32 t_idle_processor::get_next_time() const
{
	return m_next_update_time;
}

inline bool t_idle_processor::is_active() const
{
	return m_suspension_count == 0;
}

inline void t_idle_processor::set_delay( t_uint32 delay )
{
	set_next_time( m_next_update_time - m_delay + delay );
	m_delay = delay;
}

inline void t_idle_processor::set_next_time()
{
	set_next_time( m_next_update_time + m_delay );
}

class t_idle_processor_no_delay : public t_idle_processor 
{
public:
	t_idle_processor_no_delay( t_uint32 suspension_count = 0 );
	t_idle_processor_no_delay( t_idle_processor const & other );
};

#endif // !defined( IDLE_PROCESSOR_H_INCLUDED )
